package org.example.lease.custom.interceptor;

import org.example.common.login.LoginUser;
import org.example.common.login.LoginUserHolder;
import org.example.common.util.JWTUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 宋孟林
 * @description
 * @date: 2025/5/25 11:06
 */
@Component
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {
    /**
     * preHandler调用controller方法执行的
     *
     * @param request  current HTTP request
     * @param response current HTTP response
     * @param handler  chosen handler to execute, for type and/or instance evaluation
     * @return true
     * @throws Exception e
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //登录请求不会走这个拦截器，其他请求都会被拦截并且获取token
        String token = request.getHeader("access-token");
        //验证jwt合法性的逻辑在parseToken中
        Claims claims = JWTUtil.parseToken(token);
        //用户登录成功之后获取token的值，将token中的用户id和用户名取出来，放入threadLocal中
        Long userId = claims.get("userId", Long.class);
        String username = claims.get("username", String.class);
        LoginUserHolder.setLoginUser(new LoginUser(username, userId));
        log.info("当前用户id为:{}  用户的token为：{}", userId, token);
        String requestURI = request.getRequestURI();
        log.info("当前请求路径为：{}", requestURI);
        return true;
    }

    /**
     * 会在controller方法执行之后，数据在页面渲染之后执行
     * 这一步是清理 ThreadLocal 中保存的登录用户信息，避免线程复用带来的脏数据问题，非常关键！
     *
     * @param request  current HTTP request
     * @param response current HTTP response
     * @param handler  the handler (or {@link HandlerMethod}) that started asynchronous
     *                 execution, for type and/or instance examination
     * @param ex       any exception thrown on handler execution, if any; this does not
     *                 include exceptions that have been handled through an exception resolver
     * @throws Exception e
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        LoginUserHolder.remove();
    }
}
